package com.lxu.demo.classloader;


import java.io.*;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.channels.Channel;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;

public class CustomizeClassLoader  extends ClassLoader{
    public static void main(String[] args) throws Exception {
        CustomizeClassLoader classLoader = new CustomizeClassLoader();
        Class clazz =classLoader.findClass("Menu");
        System.out.println(clazz.getName());
        Method[] methods = clazz.getMethods();
        Object newInstance = clazz.newInstance();
        System.out.println(methods.length);
        for (Method method : methods) {
            if(method.getName().equals("setName")){
                method.invoke(newInstance,"xuliang");
            }
        }
        Method getName = clazz.getMethod("getName");
        System.out.println(getName.invoke(newInstance));

    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] bytes = readFile(name+".class");
        if(bytes != null){
            String className = "com.lxu.demo.tree."+name;
            Class clazz = defineClass(className,bytes,0,bytes.length);
            if(clazz!=null){
                return clazz;
            }
        }
        return super.findClass(name);
    }

    private  byte[] readFile(String name) {
        try {
            File file = new File("E:\\workspace4java\\java-learning-demos\\java-demo\\src\\main\\resources\\" + name);
            FileInputStream fis = new FileInputStream(file);
            FileChannel fileChannel = fis.getChannel();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            WritableByteChannel wbc = Channels.newChannel(baos);
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (true) {
                int i = fileChannel.read(buffer);
                if (i == 0 || i == -1) {
                    break;
                }
                buffer.flip();
                wbc.write(buffer);
                buffer.clear();
            }
            fis.close();
            return  baos.toByteArray();
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
